package cn.stylefeng.roses.kernel.saas.sdk.aop;

import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.dsctn.api.constants.DatasourceContainerConstants;
import cn.stylefeng.roses.kernel.dsctn.api.context.CurrentDataSourceContext;
import cn.stylefeng.roses.kernel.rule.constants.RuleConstants;
import cn.stylefeng.roses.kernel.saas.api.constants.SaasConstants;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;

/**
 * 租户数据源的AOP
 *
 * @author fengshuonan
 * @date 2021/2/18 17:17
 */
@Slf4j
@Aspect
public class TenantDataSourceAop implements Ordered {

    /**
     * 拦截控制器层
     */
    @Pointcut("execution(* *..controller.*.*(..))")
    public void cutService() {
    }

    @Around("cutService()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        try {
            //根据系统总开关来进行aop，获取当前用户登录的租户标识
            if (LoginContext.me().hasLogin()) {
                String tenantCode = LoginContext.me().getLoginUser().getTenantCode();
                if (StrUtil.isNotEmpty(tenantCode) && !DatasourceContainerConstants.MASTER_DATASOURCE_NAME.equals(tenantCode)) {
                    CurrentDataSourceContext.setDataSourceName(RuleConstants.TENANT_DB_PREFIX + tenantCode);
                    if (log.isDebugEnabled()) {
                        log.debug("多租户AOP--TenantSourceExAop--设置数据源为：" + tenantCode);
                    }
                }
            }
            return point.proceed();
        } finally {
            if (log.isDebugEnabled()) {
                log.debug("多租户AOP--TenantSourceExAop--清空数据源信息！");
            }
            CurrentDataSourceContext.clearDataSourceName();
        }
    }

    /**
     * aop的顺序要早于多数据源切换的
     *
     * @author fengshuonan
     * @date 2021/2/18 17:25
     */
    @Override
    public int getOrder() {
        return SaasConstants.TENANT_AOP_ORDER;
    }

}
